<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="chrome=1">

    

    <title>
      es6中Proxy和Reflect | 江月夜 
    </title>

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    
      <meta name="author" content="江月夜">
    
    

    <meta name="description" content="前言计算机中代理模式的定义：为其他对象提供一种代理以控制这个对象的访问。在某些情况下，一个对象不适合或者不能直接引用另一个对象，而代理对象可以在客户端和目标对象之间起到中介作用。 Proxy和Relect Proxy对象用于定义基本操作的自定义行为（如属性查找，赋值，枚举，函数调用等）。 Reflect是一个内置的对象">
<meta name="keywords" content="es6">
<meta property="og:type" content="article">
<meta property="og:title" content="es6中Proxy和Reflect | 江月夜">
<meta property="og:url" content="http://yoursite.com/2018/11/01/es6-Proxy-Reflect/index.html">
<meta property="og:site_name" content="江月夜">
<meta property="og:description" content="前言计算机中代理模式的定义：为其他对象提供一种代理以控制这个对象的访问。在某些情况下，一个对象不适合或者不能直接引用另一个对象，而代理对象可以在客户端和目标对象之间起到中介作用。 Proxy和Relect Proxy对象用于定义基本操作的自定义行为（如属性查找，赋值，枚举，函数调用等）。 Reflect是一个内置的对象，它提供拦截 JavaScript 操作的方法。这些方法与处理器对象的方法相同。">
<meta property="og:locale" content="zh-CN">
<meta property="og:updated_time" content="2018-11-01T09:07:24.181Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="es6中Proxy和Reflect | 江月夜">
<meta name="twitter:description" content="前言计算机中代理模式的定义：为其他对象提供一种代理以控制这个对象的访问。在某些情况下，一个对象不适合或者不能直接引用另一个对象，而代理对象可以在客户端和目标对象之间起到中介作用。 Proxy和Relect Proxy对象用于定义基本操作的自定义行为（如属性查找，赋值，枚举，函数调用等）。 Reflect是一个内置的对象，它提供拦截 JavaScript 操作的方法。这些方法与处理器对象的方法相同。">
    
    
    
      <link rel="icon" type="image/x-icon" href="/favicon.png">
    
    <link rel="stylesheet" href="/css/uno.css">
    <link rel="stylesheet" href="/css/highlight.css">
    <link rel="stylesheet" href="/css/archive.css">
    <link rel="stylesheet" href="/css/china-social-icon.css">

</head>
<body>

    <span class="mobile btn-mobile-menu">
        <i class="icon icon-list btn-mobile-menu__icon"></i>
        <i class="icon icon-x-circle btn-mobile-close__icon hidden"></i>
    </span>

    

<header class="panel-cover panel-cover--collapsed">


  <div class="panel-main">

  
    <div class="panel-main__inner panel-inverted">
    <div class="panel-main__content">

        

        <h1 class="panel-cover__title panel-title"><a href="/" title="link to homepage">江月夜</a></h1>
        <hr class="panel-cover__divider" />

        
        <p class="panel-cover__description">
          腹有诗书气自华
        </p>
        <hr class="panel-cover__divider panel-cover__divider--secondary" />
        

        <div class="navigation-wrapper">

          <nav class="cover-navigation cover-navigation--primary">
            <ul class="navigation">

              
                
                <li class="navigation__item"><a href="/#blog" title="" class="blog-button">首页</a></li>
              
                
                <li class="navigation__item"><a href="/about" title="" class="">关于</a></li>
              
                
                <li class="navigation__item"><a href="/archive" title="" class="">归档</a></li>
              

            </ul>
          </nav>

          <!-- ----------------------------
To add a new social icon simply duplicate one of the list items from below
and change the class in the <i> tag to match the desired social network
and then add your link to the <a>. Here is a full list of social network
classes that you can use:

    icon-social-500px
    icon-social-behance
    icon-social-delicious
    icon-social-designer-news
    icon-social-deviant-art
    icon-social-digg
    icon-social-dribbble
    icon-social-facebook
    icon-social-flickr
    icon-social-forrst
    icon-social-foursquare
    icon-social-github
    icon-social-google-plus
    icon-social-hi5
    icon-social-instagram
    icon-social-lastfm
    icon-social-linkedin
    icon-social-medium
    icon-social-myspace
    icon-social-path
    icon-social-pinterest
    icon-social-rdio
    icon-social-reddit
    icon-social-skype
    icon-social-spotify
    icon-social-stack-overflow
    icon-social-steam
    icon-social-stumbleupon
    icon-social-treehouse
    icon-social-tumblr
    icon-social-twitter
    icon-social-vimeo
    icon-social-xbox
    icon-social-yelp
    icon-social-youtube
    icon-social-zerply
    icon-mail

-------------------------------->

<!-- add social info here -->



<nav class="cover-navigation navigation--social">
  <ul class="navigation">

    
      <!-- Github -->
      <li class="navigation__item">
        <a href="https://github.com/ajiu9" title="">
          <i class='icon icon-social-github'></i>
          <span class="label">GitHub</span>
        </a>
      </li>
    

    <!-- China social icon -->
    <!--
    
      <li class="navigation__item">
        <a href="" title="">
          <i class='icon cs-icon-douban'></i>
          <span class="label">Douban</span>
        </a>
      </li>

      <li class="navigation__item">
        <a href="" title="">
          <i class='icon cs-icon-weibo'></i>
          <span class="label">Weibo</span>
        </a>
      </li>

    -->



  </ul>
</nav>



        </div>

      </div>

    </div>

    <div class="panel-cover--overlay"></div>
  </div>
</header>

    <div class="content-wrapper">
        <div class="content-wrapper__inner entry">
            

<article class="post-container post-container--single">

  <header class="post-header">
    
    <h1 class="post-title">es6中Proxy和Reflect</h1>

    

    <div class="post-meta">
      <time datetime="2018-11-01" class="post-meta__date date">2018-11-01</time> 

      <span class="post-meta__tags tags">

          
            <font class="categories">
            &#8226; 分类:
            <a class="categories-link" href="/categories/es6/">es6</a>
            </font>
          

          
             &#8226; 标签:
            <font class="tags">
              <a class="tags-link" href="/tags/es6/">es6</a>
            </font>
          

      </span>
    </div>
    
    

  </header>

  <section id="post-content" class="article-content post">
    <h4 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h4><p>计算机中代理模式的定义：为其他对象提供一种代理以控制这个对象的访问。在某些情况下，一个对象不适合或者不能直接引用另一个对象，而代理对象可以在客户端和目标对象之间起到中介作用。</p>
<h4 id="Proxy和Relect"><a href="#Proxy和Relect" class="headerlink" title="Proxy和Relect"></a>Proxy和Relect</h4><ul>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy" target="_blank" rel="noopener">Proxy</a>对象用于定义基本操作的自定义行为（如属性查找，赋值，枚举，函数调用等）。</li>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect" target="_blank" rel="noopener">Reflect</a>是一个内置的对象，它提供拦截 JavaScript 操作的方法。这些方法与处理器对象的方法相同。Reflect不是一个函数对象，因此它是不可构造的。</li>
</ul>
<h4 id="Proxy的方法"><a href="#Proxy的方法" class="headerlink" title="Proxy的方法"></a>Proxy的方法</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  time: <span class="string">'2018-10-31'</span>,</span><br><span class="line">  name: <span class="string">'vender'</span>,</span><br><span class="line">  _r: <span class="number">123</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> monitor = <span class="keyword">new</span> <span class="built_in">Proxy</span>(obj, &#123;</span><br><span class="line">  <span class="comment">//拦截对象读取属性值</span></span><br><span class="line">  get(target, key) &#123;</span><br><span class="line">    <span class="keyword">return</span> obj[key].replace(<span class="regexp">/-/g</span>, <span class="string">':'</span>)</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">//拦截对象设置属性值</span></span><br><span class="line">  set(target, key, value) &#123;</span><br><span class="line">    <span class="keyword">if</span> (key === <span class="string">'name'</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> target[key] = value</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> target[key]</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 拦截 key in object 操作</span></span><br><span class="line">  has(target, key) &#123;</span><br><span class="line">    <span class="keyword">if</span> (key === <span class="string">'name'</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 拦截delete</span></span><br><span class="line">  deleteProperty(target, key) &#123;</span><br><span class="line">    <span class="keyword">if</span> (key === <span class="string">'_r'</span>) &#123;</span><br><span class="line">      <span class="keyword">delete</span> target[key]</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> target[key]</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 拦截 Object.getOwnPropertyNames(),Object.getOwnProptySymbols(), Object.keys(), Reflect.ownKeys()</span></span><br><span class="line">  ownKeys(target) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Object</span>.keys(target).filter(<span class="function"><span class="params">item</span> =&gt;</span> item !== <span class="string">'time'</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>上面定义了一个对象<code>obj</code>, 同时使用了Proxy代理分别拦截了<code>get</code>,<code>set</code>,<code>has</code>,<code>deleteProperty</code>, <code>ownKeys</code>五种比较常用的方法。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'get'</span>, monitor.time) <span class="comment">// get 2018:10:31</span></span><br></pre></td></tr></table></figure></p>
<p>代理<code>get</code>方法拦截对象读取属性值。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">monitor.time = <span class="string">'2019'</span></span><br><span class="line">monitor.name = <span class="string">'apple'</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'set'</span>, monitor.name, monitor) <span class="comment">// set apple  Proxy &#123;time: "2018-10-31", name: "apple", _r: 123&#125;</span></span><br></pre></td></tr></table></figure>
<p>代理<code>set</code>方法拦截对象设置属性值。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'has'</span>, <span class="string">'name'</span> <span class="keyword">in</span> monitor, <span class="string">'time'</span> <span class="keyword">in</span> monitor) <span class="comment">// has true false</span></span><br></pre></td></tr></table></figure>
<p>代理<code>has</code>方法拦截 key in object 操作。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">delete</span> monitor.name</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'delete'</span>, monitor) <span class="comment">// delete Proxy &#123;time: "2018-10-31", name: "apple", _r: 123&#125;</span></span><br><span class="line"><span class="keyword">delete</span> monitor._r</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'delete'</span>, monitor) <span class="comment">// delete Proxy &#123;time: "2018-10-31", name: "apple"&#125;</span></span><br></pre></td></tr></table></figure>
<p>代理<code>deleteProperty</code>方法拦截delete。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'ownKeys'</span>,<span class="built_in">Object</span>.keys(monitor)) <span class="comment">// ownKeys ["name"]</span></span><br></pre></td></tr></table></figure>
<p>代理<code>ownKeys</code>方法拦截 <code>Object.getOwnPropertyNames()</code>,<code>Object.getOwnProptySymbols()</code>, <code>Object.keys()</code>,<code>Reflect.ownKeys()</code>。</p>
<h4 id="Relect的方法"><a href="#Relect的方法" class="headerlink" title="Relect的方法"></a>Relect的方法</h4><p>如前面所说，Relect的方法与处理器对象的方法相同。Reflect不是一个函数对象，因此它是不可构造的。<br>一下简单举例：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  time: <span class="string">'2018-10-31'</span>,</span><br><span class="line">  name: <span class="string">'vender'</span>,</span><br><span class="line">  _r: <span class="number">123</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'Reflect get:'</span>, <span class="built_in">Reflect</span>.get(obj, <span class="string">'time'</span>)) <span class="comment">// Reflect get: 2018-10-31</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">Reflect</span>.set(obj, <span class="string">'name'</span>, <span class="string">'banana'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'Reflect set:'</span>, obj) <span class="comment">// Reflect set: &#123;time: "2018-10-31", name: "banana", _r: 123&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'Reflect has:'</span>, <span class="built_in">Reflect</span>.has(obj, <span class="string">'time'</span>)) <span class="comment">// Reflect has: true</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">Reflect</span>.deleteProperty(obj, <span class="string">'_r'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'Reflect delete:'</span>, obj) <span class="comment">// Reflect delete: &#123;time: "2018-10-31", name: "banana"&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'Reflect ownKeys:'</span>, <span class="built_in">Reflect</span>.ownKeys(obj)) <span class="comment">// Reflect ownKeys: ["time", "name"]</span></span><br></pre></td></tr></table></figure></p>
<h4 id="简单应用"><a href="#简单应用" class="headerlink" title="简单应用"></a>简单应用</h4><p>在开发中通常会对数据进行校验，提交数据的时候会判断数据是否符合，利用<code>Proxy</code>和<code>Reflect</code>来实现一个简单的验证，实现数据和业务解耦，功能：<br>1.对用户填写的原始数据进行验证。<br>2.数据和业务解耦</p>
<p>思路：</p>
<ul>
<li>1.通过定义一个函数，这个函数的功能就是接收俩个参数(<code>target</code>原始对象和<code>validator</code>验证规则)返回一个代理对象，拦截原始对象的设置属性值，也就是<code>set</code>方法。</li>
<li>2.定义一个类<code>Person</code>,在<code>constructor</code>中重写<code>this</code>（ <code>return validator(this, personValidator)</code>这里返回的是代理对象）从而达到对这个对象实例的代理。</li>
<li>3.定义第二步这个类<code>Person</code>所需要的验证规则定义<code>personValidator</code>，在这个对象里，实现对数据的具体验证。</li>
<li>4.使用时，实例化第二步定义的类<code>Person</code>。</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">// 定义一个验证函数，这个函数返回一个代理对象。它的功能就是验证</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">validator</span>(<span class="params">target, validator</span>) </span>&#123;</span><br><span class="line">   <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Proxy</span>(target, &#123;</span><br><span class="line">     _validator: validator, <span class="comment">// 保存原始校验对象</span></span><br><span class="line">     set(target, key , value, proxy) &#123; <span class="comment">// 拦截target设置属性 </span></span><br><span class="line">       <span class="keyword">if</span> (target.hasOwnProperty(key)) &#123; <span class="comment">// target属性key存在就继续下一步，不存在抛出错误</span></span><br><span class="line">         <span class="keyword">let</span> va = <span class="keyword">this</span>._validator[key]</span><br><span class="line">         <span class="keyword">if</span> (!!va(value)) &#123; <span class="comment">// 校验规则是否通过</span></span><br><span class="line">           <span class="keyword">return</span> <span class="built_in">Reflect</span>.set(target, key, value, proxy) <span class="comment">// 拦截target设置属性，验证通过</span></span><br><span class="line">         &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">           <span class="keyword">throw</span> <span class="built_in">Error</span>(<span class="string">`<span class="subst">$&#123;key&#125;</span>不能设置为<span class="subst">$&#123;value&#125;</span>`</span>)</span><br><span class="line">         &#125;</span><br><span class="line">       &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">         <span class="keyword">throw</span> <span class="built_in">Error</span>(<span class="string">`<span class="subst">$&#123;key&#125;</span> 不存在`</span>)</span><br><span class="line">       &#125;</span><br><span class="line">     &#125;</span><br><span class="line">   &#125;)</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义验证规则</span></span><br><span class="line"> <span class="keyword">const</span> personValidator = &#123;</span><br><span class="line">   name(val) &#123;</span><br><span class="line">     <span class="keyword">return</span> <span class="keyword">typeof</span> val === <span class="string">'string'</span></span><br><span class="line">   &#125;,</span><br><span class="line">   age(val) &#123;</span><br><span class="line">     <span class="keyword">return</span> <span class="keyword">typeof</span> val === <span class="string">'number'</span> &amp;&amp; val &gt; <span class="number">18</span></span><br><span class="line">   &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 定义类</span></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">   <span class="keyword">constructor</span>(name, age) &#123;</span><br><span class="line">     <span class="keyword">this</span>.name = name</span><br><span class="line">     <span class="keyword">this</span>.age = age</span><br><span class="line">     <span class="keyword">return</span> validator(<span class="keyword">this</span>, personValidator)</span><br><span class="line">   &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实例</span></span><br><span class="line"> <span class="keyword">const</span> person = <span class="keyword">new</span> Person(<span class="string">'wu'</span>, <span class="number">20</span>)</span><br><span class="line"> <span class="built_in">console</span>.info(person)</span><br><span class="line"> </span><br><span class="line"> person.name = <span class="string">'zhuli'</span></span><br><span class="line"> <span class="built_in">console</span>.info(person) <span class="comment">// Proxy &#123;name: "hell", age: 20&#125;</span></span><br><span class="line"></span><br><span class="line"> person.age = <span class="string">'year'</span> <span class="comment">// Uncaught Error: age不能设置为year</span></span><br><span class="line"> person.dd =<span class="number">23</span></span><br></pre></td></tr></table></figure>
  </section>

  <section class="post-comments">

   <!--PC和WAP自适应版-->
<div id="SOHUCS" sid="请将此处替换为配置SourceID的语句" ></div> 
<script type="text/javascript"> 
(function(){ 
var appid = 'cytl2q04G'; 
var conf = 'prod_c6e77c75d2d767714e129c11e500044d'; 
var width = window.innerWidth || document.documentElement.clientWidth; 
if (width < 960) { 
window.document.write('<script id="changyan_mobile_js" charset="utf-8" type="text/javascript" src="https://changyan.sohu.com/upload/mobile/wap-js/changyan_mobile.js?client_id=' + appid + '&conf=' + conf + '"><\/script>'); } else { var loadJs=function(d,a){var c=document.getElementsByTagName("head")[0]||document.head||document.documentElement;var b=document.createElement("script");b.setAttribute("type","text/javascript");b.setAttribute("charset","UTF-8");b.setAttribute("src",d);if(typeof a==="function"){if(window.attachEvent){b.onreadystatechange=function(){var e=b.readyState;if(e==="loaded"||e==="complete"){b.onreadystatechange=null;a()}}}else{b.onload=a}}c.appendChild(b)};loadJs("https://changyan.sohu.com/upload/changyan.js",function(){window.changyan.api.config({appid:appid,conf:conf})}); } })(); </script>
    
</section>


</article>


            <footer class="footer">

    <span class="footer__copyright">&copy; 2017 | 由<a href="https://hexo.io/">Hexo</a>| 主题<a href="https://github.com/someus/huno">Huno</a></span>
    
</footer>
        </div>
    </div>

    <!-- js files -->
    <script src="/js/jquery.min.js"></script>
    <script src="/js/main.js"></script>
    <script src="/js/scale.fix.js"></script>
    

    

    <script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <script type="text/javascript"> 
        $(document).ready(function(){
            MathJax.Hub.Config({ 
                tex2jax: {inlineMath: [['[latex]','[/latex]'], ['\\(','\\)']]} 
            });
        });
    </script>


    

    <script src="/js/awesome-toc.min.js"></script>
    <script>
        $(document).ready(function(){
            $.awesome_toc({
                overlay: true,
                contentId: "post-content",
            });
        });
    </script>


    
    
    <!--kill ie6 -->
<!--[if IE 6]>
  <script src="//letskillie6.googlecode.com/svn/trunk/2/zh_CN.js"></script>
<![endif]-->

</body>
</html>
